#include "numericupdown.h"
#include "TextRenderer.h"
#include "..\AudioPlayer\AudioPlayer.h"

NumericUpDown::NumericUpDown(IDirect3DDevice9 *dev, int _x, int _y, int _width, int _height, int _min, int _max):device(dev),
x(_x), y(_y), width(_width), height(_height), upPressed(false), downPressed(false)
{
	min = _min;
	max = _max;
	value = max;
	if (device != NULL) Init();
}

NumericUpDown::~NumericUpDown()
{
	texture->Release();
	texturePressed->Release();
	sprite->Release();
}

void NumericUpDown::Init()
{
	D3DXCreateTextureFromFile(device, texture_string, &texture);
	D3DXCreateTextureFromFile(device, texture_pressed_string, &texturePressed);
	D3DXCreateSprite(device, &sprite);
	CalculateArrowCoords();
}

void NumericUpDown::SetDevice(IDirect3DDevice9 *dev)
{
	device = dev;
	if (device != NULL) Init();
}

void NumericUpDown::CalculateArrowCoords()
{
	int size = height / 2;

	upArrowCoords.left = x + width - size;
	upArrowCoords.right = x + width;
	upArrowCoords.top = y;
	upArrowCoords.bottom = y + size;// + 1;

	downArrowCoords.left = x + width - size;
	downArrowCoords.right = x + width;
	downArrowCoords.top = y + size;// - 1;
	downArrowCoords.bottom = y + height;

	upScaleX = float(upArrowCoords.right - upArrowCoords.left) / (float)textureSize;
	upScaleY = float(upArrowCoords.bottom - upArrowCoords.top) / (float)textureSize;
	downScaleX = float((downArrowCoords.right - downArrowCoords.left)) / (float)textureSize;
	downScaleY = float(downArrowCoords.bottom - downArrowCoords.top) / (float)textureSize;
}

bool NumericUpDown::SetValue(int val)
{
	if (val >= min && val <= max)
	{
		value = val;
		_audioPlayer->SetVolume(value);
		return true;
	}
	else
	{
		return false;
	}
}

int NumericUpDown::GetValue()
{
	return value;
}

bool NumericUpDown::IncreaseValue(int amount)
{
	if (amount > 0 && (amount + value <= max))
	{
		value += amount;
		_audioPlayer->SetVolume(value);
		return true;
	}
	else
	{
		return false;
	}
}

bool NumericUpDown::DecreaseValue(int amount)
{
	if (amount > 0 && (value - amount >= min))
	{
		value -= amount;
		_audioPlayer->SetVolume(value);
		return true;
	}
	else
	{
		return false;
	}
}

void NumericUpDown::Render()
{
	DWORD alphaBlendState;
	D3DXMATRIX res;
	//SHOULD BE DETERMINED PROGRAMMATICALLY IN THE FUTURE!!!

	device->GetRenderState(D3DRS_ALPHABLENDENABLE, &alphaBlendState);
	device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
	sprite->Begin(D3DXSPRITE_ALPHABLEND);

	// Up arrow
	D3DXVECTOR2 scale(upScaleX,	upScaleY);
	D3DXVECTOR2 rotate(0.0f, 0.0f);//((float)textureSize / 2.0, (float)textureSize / 2.0);
	D3DXVECTOR2 translate((float)upArrowCoords.left, (float)upArrowCoords.top + textureSize * upScaleY / 2);
	D3DXMatrixTransformation2D(&res, NULL, 0.0, &scale, &rotate, 0.0f, &translate);
	sprite->SetTransform(&res);
	if (!upPressed)
	{
		sprite->Draw(texture, NULL, NULL, NULL, D3DCOLOR_ARGB(255, 255, 255, 255));
	}
	else
	{
		sprite->Draw(texturePressed, NULL, NULL, NULL, D3DCOLOR_ARGB(255, 255, 255, 255));
	}

	//Down arrow
	//Some strange behavior. Should add texture size, otherwise translation will be incorrect
	translate = D3DXVECTOR2((float)downArrowCoords.left + textureSize * upScaleX,
		(float)downArrowCoords.bottom + textureSize * upScaleY / 2);
	scale = D3DXVECTOR2(downScaleX, downScaleY);
	D3DXMatrixTransformation2D(&res, NULL, 0.0, &scale, &rotate, D3DX_PI, &translate);
	sprite->SetTransform(&res);
	if (!downPressed)
	{
		sprite->Draw(texture, NULL, NULL, NULL, D3DCOLOR_ARGB(255, 255, 255, 255));
	}
	else
	{
		sprite->Draw(texturePressed, NULL, NULL, NULL, D3DCOLOR_ARGB(255, 255, 255, 255));
	}
	D3DXMatrixIdentity(&res);
	sprite->SetTransform(&res);
	TextRenderer::GetInstance().Render(sprite, x, y + height / 2, util::intToString(value));

	sprite->End();
	device->SetRenderState(D3DRS_ALPHABLENDENABLE, alphaBlendState);
}

bool NumericUpDown::MouseButtonDown(int _x, int _y, MouseButtons button)
{
	switch (button)
	{
	case MouseButtons::LeftMouseButton:
		if (_x > upArrowCoords.left && _x < upArrowCoords.right && _y > upArrowCoords.top && _y < upArrowCoords.bottom)
		{
			upPressed = true;
			return true;
		}
		if (_x > downArrowCoords.left && _x < downArrowCoords.right && _y > downArrowCoords.top && _y < downArrowCoords.bottom)
		{
			downPressed = true;
			return true;
		}
		break;
	}
	return false;
}

bool NumericUpDown::MouseButtonUp(int _x, int _y, MouseButtons button)
{
	switch (button)
	{
	case MouseButtons::LeftMouseButton:
		if (_x > upArrowCoords.left && _x < upArrowCoords.right && _y > upArrowCoords.top && _y < upArrowCoords.bottom
			&& upPressed)
		{
			IncreaseValue(2);
			upPressed = downPressed = false;
			return true;
		}
		if (_x > downArrowCoords.left && _x < downArrowCoords.right && _y > downArrowCoords.top
			&& _y < downArrowCoords.bottom && downPressed)
		{
			DecreaseValue(2);
			upPressed = downPressed = false;
			return true;
		}
		upPressed = downPressed = false;
		break;
	}
	return false;
}